<?php

/**
 * 网易短信
 */

namespace Login;


use app\common\lib\RedisKey;
use app\common\lib\RespCode;
use custom\Curl;
use custom\Log;
use custom\Redis;
use think\Exception;

class WangYiSms {

    const LOCK_TIME = 1;

    protected static $configs = [
        // 产品密钥
        'secretId'   => '5d500ab49dd4504896ace03af68fb297',
        // 产品私钥
        'secretKey'  => '490377dbe5abfa9eb8c437ec5ba59403',
        // 业务id
        'businessId' => 'cc48651e4a254dd7998d868d5bff84f8',
        // 接口版本号
        'version'    => 'v2',
        // 接口域名
        'url'        => 'https://sms.dun.163.com/v2/',
        // 短信模板id
        'templateId' => '12519',
        // 模板替换参数类型
        'paramType'  => 'json',
    ];

    /**
     * 发送短信
     * @param $mobile
     * @param $code
     * @param $time
     * @return mixed
     * @throws Exception
     */
    public static function sendAuthCode($mobile, $code, $time,$clock_key,$redis_key) {
        $redisModel = Redis::getInstance();

        // 锁
        $key = $clock_key . "_{$mobile}";
        if(!$redisModel->lock($key, self::LOCK_TIME)) {
            throw new Exception('发送太频繁');
        }

        // redis哈希映射表
        $codeData = ['code' => $code, 'expire' => time() + $time * 60];
        $res = $redisModel->hset($redis_key, $mobile, json_encode($codeData));
        if($res === false) {
            Log::write('登录验证码写入失败', 'wangyisms.log');
            return false;
        }

//        $url = 'sendsms';
//        $data = [
//            'mobile'     => (string)$mobile,
//            'templateId' => self::$configs['templateId'],
//            'params'     => json_encode([
//                'code'     => (string)$code,
//                'codeTime' => (string)$time
//            ]),
//            'paramType'  => self::$configs['paramType'],
//        ];
//        $data = array_merge($data, static::initData());
//        static::getSign($data);
//        $res = static::request($url, $data);
//        if(!isset($res['data']['result']) || $res['data']['result'] != 200) {
//            Log::write('短信接口调用失败', 'wangyisms.log');
//            return false;
//        }
        return true;
    }

    /**
     * 验证码校验
     * @param $mobile
     * @param $code
     * @throws Exception
     */
    public static function verifySms($mobile, $code,$redis_key) {
        if(config('global.dev') == 'dev') {
            if($code == '1234') {
                return true;
            }
            throw new Exception('验证码错误', RespCode::VERIFICATION_CODE_ERR);
        }
        $redisModel = Redis::getInstance();
        $codeData = $redisModel->hget($redis_key,$mobile);
        if(!$codeData = json_decode($codeData, true)) {
            throw new Exception('验证码错误', RespCode::VERIFICATION_CODE_ERR);
        }
        if($codeData['expire'] < time()) {
            throw new Exception('验证码过期', RespCode::VERIFICATION_CODE_EXPIRE);
        }
        if($codeData['code'] != $code) {
            throw new Exception('验证码错误', RespCode::VERIFICATION_CODE_ERR);
        }
        // 验证成功后删除
        $redisModel->hdel($redis_key, $mobile);
        return true;
    }

    /**
     * 生成签名
     * @param $params
     * @return string
     */
    private static function getSign(&$params) {
        ksort($params);
        $buff = "";
        foreach ($params as $key => $value) {
            $buff .= $key;
            $buff .= $value;
        }
        $buff .= self::$configs['secretKey'];
        $params['signature'] = md5(mb_convert_encoding($buff, "utf8", "auto"));
        return $params['signature'];
    }

    /**
     * 初始化数据
     * @return array
     */
    private static function initData() {
        return [
            'secretId'   => self::$configs['secretId'],
            'businessId' => self::$configs['businessId'],
            'version'    => self::$configs['version'],
            'timestamp'  => get_microtime(),
            'nonce'      => get_nonce_str(6),
        ];
    }

    /**
     * 网易短信调用
     * @param $url
     * @param array $data
     * @param string $mth
     * @return bool
     * @throws Exception
     */
    public static function request($url, $data = [], $mth = 'POST') {
        $conf = self::$configs;
        $url = $conf['url'] . $url;
        $res = Curl::getInstance()->xhr($mth, $url, http_build_query($data));
        Log::write("$url|" . json_encode($data) . '|res:' . json_encode($res), 'wang_yi_sms.log');
        if (empty($res)) {
            throw new Exception('短信接口调用失败');
        }
        $res = json_decode($res, true);
        if (!isset($res['code']) || $res['code'] != 200) {
            throw new Exception('短信接口调用失败');
        }

        return $res;
    }

}
